using System;
using System.Collections.Generic;
using System.Dynamic;

namespace Se.Framework.Logging
{
    internal static class ILogSourceExtentions
    {
        public static log4net.ILog GetLogger(this ILogSource source)
        {
            log4net.ThreadContext.Properties["logSource"] = source.SourceId;
            log4net.ThreadContext.Properties["logSourceReference"] = source.SourceReference;
            if (source.ExtendedLogData != null)
                SetCustomProperties(source.ExtendedLogData);

            return log4net.LogManager.GetLogger(source.SourceName);
        }

        private static readonly ReflectionCache<System.Reflection.PropertyInfo[]> propertiesCache = new ReflectionCache<System.Reflection.PropertyInfo[]>(o => o.GetProperties());

        private static void SetCustomProperties(dynamic source)
        {
            if (source != null)
            {
                if (source is ExpandoObject)
                {
                    foreach (var property in (IDictionary<string, object>)source)
                    {
                        if (property.Value.GetType() == typeof(ExpandoObject))
                            SetCustomProperties(property.Value);
                        else
                            if (property.Value.GetType() == typeof(List<dynamic>))
                                foreach (var element in (List<dynamic>)property.Value)
                                    SetCustomProperties(element);
                            else
                                log4net.ThreadContext.Properties["log" + property.Key] = property.Value;

                    }
                }
                else
                {
                    Type sourceType = source.GetTypeByClassName();
                    foreach (var property in propertiesCache.GetValue(sourceType))
                    {
                        log4net.ThreadContext.Properties["log" + property.Name] = property.GetValue(source, null);
                    }
                }
            }
        }
    }
}